package stw.brassdawn.map;

import java.awt.Dimension;
import java.awt.Point;

public class GameMap {
	public static final Dimension DEFAULT_MAP_SIZE = new Dimension( 10, 20 );
	
	private Dimension myMapSize;
	private MapPosition[][] myGameBoard;
	
	public GameMap( ) {
		this( GameMap.DEFAULT_MAP_SIZE );
	}
	
	public GameMap( Dimension mapSize ) {
		if( mapSize == null || mapSize.height <= 0 || mapSize.width <= 0 )
			myMapSize = GameMap.DEFAULT_MAP_SIZE;
		else 
			myMapSize = mapSize;
		
		initGameBoard( );
	}
	
	private void initGameBoard( ) {
		myGameBoard = new MapPosition[myMapSize.width][myMapSize.height];
		for( int i = 0; i < myGameBoard.length; i++ ) {
			for( int j = 0; j < myGameBoard[i].length; j++ ) {
				myGameBoard[i][j] = new MapPosition();
			}
		}
	}
	
	public Dimension getMapSize( ) {
		return myMapSize;
	}
	
	/**
	 * Validates and sets the given unit id into the position given.
	 * @param position
	 * @param unitID
	 * @return The unitID if placement was successful, INVALID_POSITION, OCCUPIED, and DUPLICATE_UNIT if not successful.
	 */
	public int setUnitAt( Point position, int unitID ) {
		if( !validPoint( position ) ) {
			return MapPosition.INVALID_POSITION;
		} else if( myGameBoard[position.x][position.y].getUnitID() == MapPosition.EMPTY ) {
			return MapPosition.OCCUPIED;
		} else if( containsUnit( unitID )) {
			return MapPosition.DUPLICATE_UNIT;
		} 
		
		myGameBoard[position.x][position.y].setUnitID(unitID);
		return unitID;
	}
	
	/**
	 *  Returns the unit identifier at the given point.
	 *  
	 * @param position the unit to return
	 * @return The unit identifier or MapPosition.INVALID_POSITION or MapPosition.EMPTY
	 */
	public int getUnitAt( Point position ) {
		if( !validPoint(position)) {
			return MapPosition.INVALID_POSITION;
		} 
		
		return myGameBoard[position.x][position.y].getUnitID();
	}
	
	public boolean containsUnit( int unitID ) {
		boolean rv = false;
		for( int i = 0; i < myGameBoard.length; i++ ) {
			for( int j = 0; j < myGameBoard[i].length; j++ ) {
				if( unitID == myGameBoard[i][j].getUnitID() ) {
					rv = true;
					break;
				}
			}
		}
		return rv;
	}
	
	/**
	 * Validates the given point against the size of the map to make sure the point is within bounds.
	 * 
	 * @param position the point to check
	 * @return <code>true</code> if the point is within the game map size
	 */
	public boolean validPoint( Point position ) {
		boolean rv = true;
		if( position.x < 0 || position.y < 0 )
			rv = false;
		if( position.x > myMapSize.width || position.y > myMapSize.height ) 
			rv = false;
		return rv;
	}
}
